﻿

namespace TY.GateWay
{
    using System;
    using System.IO;
    using System.Net;
    using System.Security.Cryptography.X509Certificates;
    using System.Threading.Tasks;
    using DotNetty.Buffers;
    using DotNetty.Codecs;
    using DotNetty.Codecs.Protobuf;
    using DotNetty.Handlers.Logging;
    using DotNetty.Handlers.Tls;
    using DotNetty.Transport.Bootstrapping;
    using DotNetty.Transport.Channels;
    using DotNetty.Transport.Channels.Sockets;
    using Google.Protobuf;
    using MO.Protocol;

    class Program
    {
        static async Task RunServerAsync()
        {


            var bossGroup = new MultithreadEventLoopGroup(4);
            var workerGroup = new MultithreadEventLoopGroup();

            var STRING_ENCODER = new ProtobufEncoder();
            var STRING_DECODER = new ProtobufDecoder(BasicMessage.Parser);
            var SERVER_HANDLER = new ServerHandler();


            try
            {
                var bootstrap = new ServerBootstrap();
                bootstrap
                    .Group(bossGroup, workerGroup)
                    .Channel<TcpServerSocketChannel>()
                    .Option(ChannelOption.SoKeepalive, true)
                    .Option(ChannelOption.TcpNodelay, true)
                    .Option(ChannelOption.SoBacklog, 100)
                     .Option(ChannelOption.SoReuseaddr, true)
                    .Handler(new LoggingHandler(LogLevel.TRACE))
                    .ChildHandler(new ActionChannelInitializer<ISocketChannel>(channel =>
                    {
                        IChannelPipeline pipeline = channel.Pipeline;

                        //         pipeline.AddLast(new LengthFieldPrepender(
                        //ByteOrder.LittleEndian, 2, 0, false));
                        //         pipeline.AddLast(new LengthFieldBasedFrameDecoder(
                        //             ByteOrder.LittleEndian, UInt16.MaxValue, 0, 2, 0, 2, true));
                        //pipeline.AddLast(new DelimiterBasedFrameDecoder(8192, Delimiters.LineDelimiter()));
                        //pipeline.AddLast(new StringEncoder());
                        //pipeline.AddLast(new StringDecoder());
                        pipeline.AddLast(STRING_ENCODER);
                        pipeline.AddLast(STRING_DECODER);
                        pipeline.AddLast(SERVER_HANDLER);
                    }));
                IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 9999);
                IChannel bootstrapChannel = await bootstrap.BindAsync(endPoint);

                Console.ReadLine();

                await bootstrapChannel.CloseAsync();
            }
            finally
            {
                Task.WaitAll(bossGroup.ShutdownGracefullyAsync(), workerGroup.ShutdownGracefullyAsync());
            }
        }

        static void Main() => RunServerAsync().Wait();
    }
}
